﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Compiled_Tests.Utils;
using System.Diagnostics;
using Compiled_Tests;
using Compiled_Tests.ProcessWrappers;
using LEET.Utilities;
using LEET.LEETCommon;

namespace Compiled_Tests
{
    public class ProcessController
    {
        private Box box;
        internal IDictionary<String, Process> processes;
        internal Queue<IProcess> toWatch;
        internal Queue<IProcess> processWatch;
        internal List<int> processId { get; private set; }

        public ProcessController(Queue<IProcess> processWatch, Box boxes)
        {
            toWatch = processWatch;
            box = boxes;

            processes = new Dictionary<String, Process>();
            box.Processes = (delegate () { return processes.Keys; });
            processId = new List<int>();
        }

        public void Enque(IProcess p)
        {
            if (processes.ContainsKey(p.Name) && processes[p.Name].HasExited)
            {
                processes.Remove(p.Name);
                processId.Remove(p.Process.Id);
            }
            Process proc = getProcess(p);
            if (!processes.Keys.Contains(p.Name))
            {
                processes.Add(p.Name, proc);
                processId.Add(p.Process.Id);
            }
            toWatch.Enqueue(new ProcessWrapper(proc, p.Name)); 
        }

        public void Target(IProcess p)
        {
            Process proc = getProcess(p);
            box.RootElement = Utilities.Get_MainAE(proc);
        }

        private Process getProcess(IProcess p)
        {
            Process proc = Helpers.Poll(delegate()
            {
                Process ret = null;
                processes.TryGetValue(p.Name, out ret);
                return ret;
            }, 100, 2000, null as Process);
            if (proc == null)
            {
                proc = p.Process;
            }
            return proc;
        }

        internal void KillAll()
        {

            foreach (Process proc in processes.Values)
            {
                if (!proc.HasExited)
                {
                    try { proc.CloseMainWindow(); } catch { }
                    try { proc.Kill(); } catch { }
                }
            }
        }

        public int ProcessCount
        {
            get { return processes.Keys.Count; }
        }


        public string DumpErrors { get {
            StringBuilder buf = new StringBuilder();
            buf.AppendLine("Process Error Dump:");
            foreach(Process proc in processes.Values)
            {
                try
                {
                    buf.AppendLine(proc.StandardError.ReadToEnd());
                }
                catch { }
            }
            return buf.ToString();
        } }
    }
}
